<template>
  <div ref="myChart" :style="style"></div>
</template>

<script setup lang="ts">
import {
  computed,
  ref,
  watch,
  nextTick,
  onBeforeUnmount,
  useAttrs,
  onMounted
} from 'vue'

import * as echarts from 'echarts'

import chartProps from './props'

import { validEvents } from './hooks'

defineOptions({
  name: 'chart',
  // 防止继承
  inheritAttrs: false
})

const style = computed(() => {
  return {
    width: props.width,
    height: props.height
  }
})

const props = defineProps(chartProps)

const myChart = ref<HTMLElement>()
let chartInstance: any | null = null

// 拿到 继承 属性 或 方法
const attrs = useAttrs()

watch(
  () => props.options,
  () => {
    nextTick(() => {
      initOptions()
    })
  },
  {
    deep: true
  }
)

onMounted(() => {
  initOptions()
})

async function getEchartsInstance() {
  await nextTick()
  return chartInstance
}

function initOptions() {
  if (!myChart.value) return

  chartInstance = echarts.init(myChart.value)
  if (props.options && typeof props.options === 'object') {
    chartInstance && chartInstance.setOption(props.options)
  }

  // 注册事件
  // 注意： inheritAttrs要设置false，否则会出现事件继承，调用两次，vue3特性
  Object.entries(attrs).forEach(([emit, fn]) => {
    if (validEvents.includes(emit)) {
      chartInstance.on(emit.substring(2), fn)
    }
  })

  window.addEventListener('resize', resize)
}

function resize() {
  setTimeout(() => {
    chartInstance && chartInstance.resize()
  }, 50)
}

function destruction() {
  chartInstance && echarts.dispose(chartInstance)
  window.removeEventListener('resize', resize)
}

onBeforeUnmount(() => {
  destruction()
})

defineExpose({
  getEchartsInstance
})
</script>

<style scoped></style>
